package com.wrupple.muba.catalogs.client.module.services.presentation.impl;

import com.google.gwt.cell.client.Cell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.cellview.client.CellWidget;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.view.client.ProvidesKey;
import com.google.gwt.view.client.SimpleKeyProvider;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.wrupple.muba.catalogs.client.CatalogFieldMap;
import com.wrupple.muba.catalogs.client.activity.process.task.CatalogInteractionState.Mode;
import com.wrupple.muba.catalogs.client.module.services.logic.GenericDataProvider;
import com.wrupple.muba.catalogs.client.module.services.presentation.FilterableDataProvider;
import com.wrupple.muba.catalogs.client.module.services.presentation.GenericFieldFactory;
import com.wrupple.muba.catalogs.client.widgets.editors.ForeignValueRelationEditor.RelationshipDelegate;
import com.wrupple.muba.catalogs.client.widgets.editors.composite.delegates.ForeignValueRelationEditorImpl;
import com.wrupple.muba.common.shared.State.ProcessManager;
import com.wrupple.vegetate.domain.FieldDescriptor;

public class GenericFieldFactoryImpl implements GenericFieldFactory {
	
	protected CatalogFieldMap widgetter;
	private ProvidesKey<Object> keyProvider;
	private Provider<GenericDataProvider> providerProvider;
	
	@Inject
	public GenericFieldFactoryImpl(CatalogFieldMap widgetter, Provider<GenericDataProvider> providerProvider) {
		super();
		this.providerProvider=providerProvider;
		this.widgetter = widgetter;
		keyProvider = new SimpleKeyProvider<Object>();
	}

	@Override
	public  HasValue<Object> getOrCreateField(
			FieldDescriptor field, Mode mode, EventBus bus, ProcessManager pm,
			RelationshipDelegate delegate) {
		Cell cell = null;
		
		try {
			cell =  widgetter.get(field.getWidget()).createCell(bus, pm, field, mode);
		} catch (NullPointerException e) {
			GWT.log("Unable to find cell suitable for field " + field.getName() 
					+ " with widget id:" + field.getWidget(), e);
			return null;	
		}
		
		HasValue  regreso;
		if(field.isEphemeral()||field.isKey()){
			FilterableDataProvider dataProvider = providerProvider.get();
			dataProvider.setCatalog(field.getForeignCatalog());
			ForeignValueRelationEditorImpl editor = new ForeignValueRelationEditorImpl(delegate,cell,dataProvider);
			// provided cell handles foreign values
			regreso = editor;
			
		}else{
			regreso =  new CellWidget<Object>(cell,keyProvider);
		}
		
		return regreso;
	}


}
